package com.cdck.safe.dete.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdck.safe.dete.model.entity.CheckProject;
import com.cdck.safe.dete.model.entity.CheckRecord;
import com.cdck.safe.dete.mapper.CheckRecordMapper;
import com.cdck.safe.dete.model.entity.SysUser;
import com.cdck.safe.dete.model.query.BaseKeywordsQuery;
import com.cdck.safe.dete.model.vo.CheckRecordVO;
import com.cdck.safe.dete.service.CheckProjectService;
import com.cdck.safe.dete.service.CheckRecordService;
import com.cdck.safe.dete.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (CheckRecord)表服务实现类
 *
 * @author Sakura
 * @since 2024-02-29 10:19:59
 */
@Service
@RequiredArgsConstructor
public class CheckRecordServiceImpl extends ServiceImpl<CheckRecordMapper, CheckRecord> implements CheckRecordService {

    @Resource
    private SysUserService userService;

    @Resource
    private CheckProjectService checkProjectService;

    /**
     * 已检查
     */
    private static final String IS_CHECK = "1";
    /**
     * 未检查
     */
    private static final String NOT_CHECK = "0";

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public CheckRecord getCheckRecordFormData(Long id) {
        return this.getById(id);
    }

    /**
     * 分页查询
     *
     * queryParams 筛选条件
     * @return 查询结果
     */
    @Override
    public IPage<CheckRecordVO> queryByPage(BaseKeywordsQuery queryParams){
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();
        Page<CheckRecord> page = new Page<>(pageNum, pageSize);
        Page<CheckRecordVO> pageVO = new Page<>(pageNum, pageSize);
        List<Long> userIds = new ArrayList<>();
        List<Long> projectIds = new ArrayList<>();
        //设置过滤体条件
        if (StrUtil.isNotBlank(keywords)) {
            LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.like(SysUser::getNickname, keywords);
            List<SysUser> sysUserList = userService.list(userWrapper);
            userIds = sysUserList.stream().map(item -> item.getId()).collect(Collectors.toList());

            //实验室编号 或者用户的预约
            LambdaQueryWrapper<CheckProject> labWrapper = new LambdaQueryWrapper<>();
            labWrapper.like(CheckProject::getName, keywords);
            List<CheckProject> projectList = checkProjectService.list(labWrapper);
            projectIds = projectList.stream().map(item -> item.getId()).collect(Collectors.toList());
        }

        //如果bookIds的size为0 返回空
        if (StrUtil.isNotBlank(keywords)&&userIds.size() == 0&&projectIds.size() == 0) {
            return pageVO;
        }
        //二者只有一个为空
        LambdaQueryWrapper<CheckRecord> queryWrapper = new LambdaQueryWrapper<CheckRecord>();
        if (StrUtil.isNotBlank(keywords)&&userIds.size() > 0) {
            queryWrapper.in(CheckRecord::getUserId, userIds);
        }
        if (StrUtil.isNotBlank(keywords) && projectIds.size() > 0) {
            queryWrapper.or().in(CheckRecord::getProjectId, projectIds);
        }
        queryWrapper.orderByDesc(CheckRecord::getUpdateTime);
        Page<CheckRecord> recordPage = this.page(
                page,
                queryWrapper
        );
        List<CheckRecordVO> recordVOList = recordPage.getRecords().stream().map(item -> {
            CheckRecordVO vo = new CheckRecordVO();
            BeanUtils.copyProperties(item, vo);
            SysUser user = userService.getById(item.getUserId());
            if (user != null) {
                vo.setUserName(user.getNickname());
            }
            CheckProject checkProject = checkProjectService.getById(item.getProjectId());
            if (checkProject != null) {
                vo.setProjectName(checkProject.getName());
            }
            return vo;
        }).collect(Collectors.toList());
        BeanUtils.copyProperties(page, pageVO, "records");
        pageVO.setRecords(recordVOList);
        return pageVO;
     }

    /**
     * 新增数据
     *
     * @param checkRecord 实例对象
     * @return 实例对象
     */
    @Override
    public boolean saveCheckRecord(CheckRecord checkRecord) {
       return this.save(checkRecord);
    }

    /**
     * 修改数据
     *
     * @param checkRecord 实例对象
     * @return 实例对象
     */
    @Override
    public boolean updateCheckRecord(Long id, CheckRecord checkRecord) {
         return this.updateById(checkRecord);
    }

    /**
     * 通过主键删除数据
     *
     * @param idsStr ids集合
     * @return 是否成功
     */
    @Override
    public boolean deleteCheckRecords(String idsStr) {
         Assert.isTrue(StrUtil.isNotBlank(idsStr), "删除的数据为空");
        // 逻辑删除
        List<Long> ids = Arrays.stream(idsStr.split(","))
                .map(Long::parseLong).collect(Collectors.toList());
        return this.removeByIds(ids);
    }

    @Override
    public Boolean isChecking(Long userId, String projectId) {
        LambdaQueryWrapper<CheckRecord> wrapper = new LambdaQueryWrapper<>();
        LocalDateTime now = LocalDateTime.now();
        Date todayZero = Date.from(now.truncatedTo(ChronoUnit.DAYS).atZone(ZoneId.systemDefault()).toInstant());
        wrapper.eq(CheckRecord::getUserId, userId)
                .eq(CheckRecord::getProjectId, projectId)
                .isNull(CheckRecord::getEndTime)
                .eq(CheckRecord::getFinished, NOT_CHECK)
                .ge(CheckRecord::getStartTime, todayZero);
        CheckRecord one = this.getOne(wrapper);
        return Objects.nonNull(one);
    }
}
